home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1998 November / Freeware November 1998.img / dist / fw_GGxli.idb / usr / freeware / src / xli-1.16 / rotate.c.z / rotate.c
C/C++ Source or Header  |  1997-09-09  |  6KB  |  190 lines

  1. /* #ident    "@(#)x11:contrib/clients/xloadimage/rotate.c 1.8 93/07/23 Labtam" */
  2. /* rotate.c
  3.  *
  4.  * rotate an image
  5.  *
  6.  * Contributed by Tom Tatlow (tatlow@dash.enet.dec.com)
  7.  */
  8.  
  9. #include "copyright.h"
  10. #include "xli.h"
  11.  
  12. /* rotate_bitmap()
  13.  * converts an old bitmap bit position into a new one
  14.  */
  15. void rotate_bitmap(num, pos, width, height, new_num, new_pos)
  16. int      num;                /* Source byte number       */
  17. int      pos;                /* Source bit position      */
  18. int    width;                /* Width of source bitmap   */
  19. int   height;                /* Height of source bitmap  */
  20. int *new_num;                /* Destination byte number  */
  21. int *new_pos;                /* Destination bit position */
  22. {
  23.   int   slen;                /* Length of source line      */
  24.   int   dlen;                /* Length of destination line */
  25.   int sx, sy;
  26.   int dx, dy;
  27.  
  28.   slen = (width / 8) + (width % 8 ? 1 : 0);
  29.   dlen = (height / 8) + (height % 8 ? 1 : 0);
  30.   sy = num / slen;
  31.   sx = ((num - (sy * slen)) * 8) + pos;
  32.   dx = (height - sy) - 1;
  33.   dy = sx;
  34.   *new_num = (dx / 8) + (dy * dlen);
  35.   *new_pos = dx % 8;
  36. }
  37.  
  38. /* rotate()
  39.  * rotates an image
  40.  */
  41. Image *rotate(iimage, rotate, verbose)
  42. Image *iimage;                /* Image to rotate             */
  43. int    rotate;                /* Number of degrees to rotate */
  44.   int          rot;            /* Actual rotation             */
  45.   Image    *simage;            /* Source image                */
  46.   Image    *dimage;            /* Destination image           */
  47.   byte         *sp;            /* Pointer to source data      */
  48.   byte         *dp;            /* Pointer to destination data */
  49.   int     slinelen;            /* Length of source line       */
  50.   int     dlinelen;            /* Length of destination line  */
  51.   int       bit[8];            /* Array of hex values         */
  52.   int         x, y;
  53.   int         i, b;
  54.   int   newx, newy;
  55.   int   newi, newb;
  56.   byte      **yptr;
  57.  
  58.   bit[0] = 128;
  59.   bit[1] =  64;
  60.   bit[2] =  32;
  61.   bit[3] =  16;
  62.   bit[4] =   8;
  63.   bit[5] =   4;
  64.   bit[6] =   2;
  65.   bit[7] =   1;
  66.  
  67.   CURRFUNC("rotate");
  68.  
  69.   if (verbose)
  70.     { printf("  Rotating image by %d degrees...", rotate);
  71.       fflush(stdout);
  72.     }
  73.  
  74.   simage = iimage;
  75.   for(rot=0;rot < rotate; rot +=90) {
  76.     switch (simage->type) {
  77.     case IBITMAP:
  78.       dimage= newBitImage(simage->height, simage->width);
  79.       for (x= 0; x < simage->rgb.used; x++) {
  80.     *(dimage->rgb.red + x)= *(simage->rgb.red + x);
  81.     *(dimage->rgb.green + x)= *(simage->rgb.green + x);
  82.     *(dimage->rgb.blue + x)= *(simage->rgb.blue + x);
  83.       }
  84.       slinelen= (simage->width / 8) + (simage->width % 8 ? 1 : 0);
  85.       sp = simage->data;
  86.       dp = dimage->data;
  87.       for (i = 0; i < (slinelen * simage->height); i++)
  88.     for (b = 0; b < 8; b++)
  89.       if (sp[i] & bit[b])
  90.         { rotate_bitmap(i, b, simage->width, simage->height, &newi, &newb);
  91.           dp[newi] |= bit[newb];
  92.         }
  93.       break;
  94.       
  95.     case IRGB:
  96.       dimage= newRGBImage(simage->height, simage->width, simage->depth);
  97.       for (x= 0; x < simage->rgb.used; x++) {
  98.     *(dimage->rgb.red + x)= *(simage->rgb.red + x);
  99.     *(dimage->rgb.green + x)= *(simage->rgb.green + x);
  100.     *(dimage->rgb.blue + x)= *(simage->rgb.blue + x);
  101.       }
  102.       dimage->rgb.used= simage->rgb.used;
  103.  
  104.       /* build array of y axis ptrs into destination image
  105.        */
  106.  
  107.       yptr= (byte **)lmalloc(simage->width * sizeof(char *));
  108.       dlinelen= simage->height * dimage->pixlen;
  109.       for (y= 0; y < simage->width; y++)
  110.     yptr[y]= dimage->data + (y * dlinelen);
  111.  
  112.       /* rotate
  113.        */
  114.  
  115.       sp= simage->data;
  116.       if(simage->pixlen == 1 && dimage->pixlen == 1)    /* most common */
  117.         for (y = 0; y < simage->height; y++)
  118.           for (x = 0; x < simage->width; x++) {
  119.             register unsigned long temp;
  120.             temp = memToVal(sp, 1);
  121.             valToMem(temp, yptr[x] + (simage->height - y - 1),1);
  122.             sp += 1;
  123.           }
  124.       else    /* less common */
  125.         for (y = 0; y < simage->height; y++)
  126.           for (x = 0; x < simage->width; x++) {
  127.             register unsigned long temp;
  128.             temp = memToVal(sp, simage->pixlen);
  129.             valToMem(temp,
  130.                  yptr[x] + ((simage->height - y - 1) * dimage->pixlen),
  131.                  dimage->pixlen);
  132.             sp += simage->pixlen;
  133.           }
  134.       lfree(yptr);
  135.       break;
  136.  
  137.     case ITRUE:
  138.       if (TRUEP(simage))
  139.     dimage= newTrueImage(simage->height, simage->width);
  140.  
  141.       /* build array of y axis ptrs into destination image
  142.        */
  143.  
  144.       yptr= (byte **)lmalloc(simage->width * sizeof(char *));
  145.       dlinelen= simage->height * dimage->pixlen;
  146.       for (y= 0; y < simage->width; y++)
  147.     yptr[y]= dimage->data + (y * dlinelen);
  148.  
  149.       /* rotate
  150.        */
  151.  
  152.       sp= simage->data;
  153.       if(simage->pixlen == 3 && dimage->pixlen == 3)    /* most common */
  154.         for (y = 0; y < simage->height; y++)
  155.           for (x = 0; x < simage->width; x++) {
  156.             register unsigned long temp;
  157.             temp = memToVal(sp, 3);
  158.             valToMem(temp, yptr[x] + ((simage->height - y - 1) * 3),3);
  159.             sp += 3;
  160.           }
  161.       else    /* less common */
  162.         for (y = 0; y < simage->height; y++)
  163.           for (x = 0; x < simage->width; x++) {
  164.             register unsigned long temp;
  165.             temp = memToVal(sp, simage->pixlen);
  166.             valToMem(temp,
  167.                  yptr[x] + ((simage->height - y - 1) * dimage->pixlen),
  168.                  dimage->pixlen);
  169.             sp += simage->pixlen;
  170.           }
  171.       lfree(yptr);
  172.       break;
  173.     default:
  174.       printf("rotate: Unsupported image type\n");
  175.       exit(1);
  176.     }
  177.   if(simage != iimage)
  178.     freeImage(simage);
  179.   simage = dimage;
  180.   }
  181.   dimage->title= (char *)lmalloc(strlen(iimage->title) + 40);
  182.   sprintf(dimage->title, "%s (rotated by %d degrees)", iimage->title, rot);
  183.   dimage->gamma= iimage->gamma;
  184.   if (verbose)
  185.     printf("done\n");
  186.   return(dimage);
  187. }
  188.  
  189.